package dev.ece.suit.hexmap.terrain;

import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL11;

import com.bulletphysics.collision.shapes.BvhTriangleMeshShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.TriangleIndexVertexArray;

import dev.ece.core.light.Material;
import dev.ece.core.texture.Texture;
import dev.ece.suit.hexmap.HexMapCell;
import dev.ece.suit.hexmap.HexMapCellIndex;
import dev.ece.suit.hexmap.HexMapChunks;
import dev.ece.suit.hexmap.HexMapCrevice;
import dev.ece.suit.hexmap.HexMapTriangle;
import dev.ece.suit.hexmap.HexMapWaterCell;
import dev.ece.suit.hexmap.terrain.type.TerrainType;
import dev.ece.util.GeoUtils;
import dev.ece.util.lib.Matrix4f;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.tools.BufferBuilder;
import dev.ece.util.tools.Constants;
import dev.ece.util.tools.Direction;
import dev.ece.util.tools.NormalUtils;
import dev.ece.util.tools.ploy.TextureMipmapPloy;

@Deprecated
public class DefaultTerrainFactory extends AbstractTerrainFactory implements TerrainFactory {
	
	private final Logger log = LogManager.getLogger(getClass());
	
	public static final int CREVICE_VERTICE_SIZE = 4;
	
	public static final float[] CREVICE_VERTICE_ALPHA = new float[CREVICE_VERTICE_SIZE];
	
	public final static int TRIANGLE_VERTICE_SIZE = 3;
	
	public final static Vector2f[] TRIANGLE_VERTICE_ALPHA = new Vector2f[TRIANGLE_VERTICE_SIZE];
	
	public static final int VERTICE_SIZE = 8;
	
	static {
		CREVICE_VERTICE_ALPHA[0] = 0;
		CREVICE_VERTICE_ALPHA[1] = 0;
		
		CREVICE_VERTICE_ALPHA[2] = 1.0f;
		CREVICE_VERTICE_ALPHA[3] = 1.0f;
		
		TRIANGLE_VERTICE_ALPHA[0] = new Vector2f(1, 0);
		TRIANGLE_VERTICE_ALPHA[1] = new Vector2f(0, 1);
		TRIANGLE_VERTICE_ALPHA[2] = new Vector2f(0, 0);
	}
	
	public final Vector3f[] vertice = new Vector3f[VERTICE_SIZE];
	
	public final Vector2f[] uv = new Vector2f[VERTICE_SIZE];
	
	public final Vector3f[] waterVertice = new Vector3f[VERTICE_SIZE];
	
	public final Vector2f[] waterUv = new Vector2f[VERTICE_SIZE];
	
	private float cellOutSize;
	
	private float cellInSize;
	
	private String[] texture_paths;
	
	private BufferedImage[] texture_images;
	
	private Texture[] textures;
	
	private TerrainType[] terrainTypes;
	
	private Material waterMaterial;
	
	private TerrainRenderer cellTerrainRenderer = new TerrainRenderer() {

		@Override
		public void setup() {}

		@Override
		public void render(int first) {
			GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, first, VERTICE_SIZE);
		}

		@Override
		public boolean isIntersected(Vector3f o, Vector3f dir, List<Vector3f> vertice, Vector3f result) {
			Vector3f v0 = vertice.get(0);
			int size = VERTICE_SIZE - 1;
			for(int i=1; i<size; i++) {
				if(GeoUtils.intersectTriangle(o, dir, v0, vertice.get(i), vertice.get(i + 1), result)) {
					return true;
				}
			}
			return false;
		}
		
	};
	
	private TerrainRenderer creviceTerrainRenderer = new TerrainRenderer() {

		@Override
		public void setup() {}

		@Override
		public void render(int first) {
			GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, first, CREVICE_VERTICE_SIZE);
		}

		@Override
		public boolean isIntersected(Vector3f o, Vector3f dir, List<Vector3f> vertice, Vector3f result) {
			if(GeoUtils.intersectTriangle(o, dir, vertice.get(0), vertice.get(1), vertice.get(2), result)) {
				return true;
			}
			if(GeoUtils.intersectTriangle(o, dir, vertice.get(2), vertice.get(1), vertice.get(3), result)) {
				return true;
			}
			return false;
		}
		
	};

	private TerrainRenderer triangleTerrainRenderer = new TerrainRenderer() {

		@Override
		public void setup() {}

		@Override
		public void render(int first) {
			GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, first, TRIANGLE_VERTICE_SIZE);
		}

		@Override
		public boolean isIntersected(Vector3f o, Vector3f dir, List<Vector3f> vertice, Vector3f result) {
			if(GeoUtils.intersectTriangle(o, dir, vertice.get(0), vertice.get(1), vertice.get(2), result)) {
				return true;
			}
			return false;
		}
		
	};
	
	private List<HexMapCellIndex> waterCellIndex = new ArrayList<HexMapCellIndex>();
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, String[] texture_paths) {
		this(terrainTypes, 1f, texture_paths);
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, Texture[] textures) {
		this(terrainTypes, 1f, textures);
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, BufferedImage[] texture_images) {
		this(terrainTypes, 1f, texture_images);
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, String[] texture_paths) {
		this(terrainTypes, cellOutSize, texture_paths, new Material());
		setDefaultMaterial();
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, Texture[] textures) {
		this(terrainTypes, cellOutSize, textures, new Material());
		setDefaultMaterial();
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, BufferedImage[] texture_images) {
		this(terrainTypes, cellOutSize, texture_images, new Material());
		setDefaultMaterial();
	}
	
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, BufferedImage[] texture_images, Material waterMaterial) {
		this.terrainTypes = terrainTypes;
		this.texture_images = texture_images;
		this.waterMaterial = waterMaterial;
		this.cellOutSize = cellOutSize;
		this.cellInSize = cellOutSize * (float) Math.sin(Math.toRadians(60));
		this.init();
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, Texture[] textures, Material waterMaterial) {
		this.terrainTypes = terrainTypes;
		this.textures = textures;
		this.waterMaterial = waterMaterial;
		this.cellOutSize = cellOutSize;
		this.cellInSize = cellOutSize * (float) Math.sin(Math.toRadians(60));
		this.init();
	}
	
	public DefaultTerrainFactory(TerrainType[] terrainTypes, float cellOutSize, String[] texture_paths, Material waterMaterial) {
		this.terrainTypes = terrainTypes;
		this.texture_paths = texture_paths;
		this.waterMaterial = waterMaterial;
		this.cellOutSize = cellOutSize;
		this.cellInSize = cellOutSize * (float) Math.sin(Math.toRadians(60));
		this.init();
	}
	
	protected void setDefaultMaterial() {
		waterMaterial.getDiffuse().set(0.8f, 0.8f, 0.8f);
		waterMaterial.getSpecular().set(0.6f, 0.6f, 0.6f);
		waterMaterial.setShininess(8f);
		waterMaterial.setAlpha(0.6f);
	}
	
	protected void init() {
		Matrix4f matrix = new Matrix4f();
		vertice[0] = new Vector3f();
		waterVertice[0] = new Vector3f();
		Vector3f point = null;
		float height = 0.1f;
		float waterSize = (float) (this.cellOutSize / Math.sin(Math.toRadians(60)));
		for(int i=1; i<vertice.length; i++) {
			matrix.identity();
			matrix.rotate(0, 1f, 0, 60f * (i - 1));
			point = new Vector3f(0, height, -this.cellOutSize);
			matrix.transform(point);
			vertice[i] = point;
			
			point = new Vector3f(0, 0, -waterSize);
			matrix.transform(point);
			waterVertice[i] = point;
		}
		vertice[7] = vertice[1];
		waterVertice[7] = waterVertice[1];
		
		matrix.identity();
		matrix.translate(cellInSize, 0, cellOutSize);
		
		for(int i=0; i<vertice.length - 1; i++) {
			matrix.transform(vertice[i]);
			matrix.transform(waterVertice[i]);
		}
		
		float outsize = 0.5f;
		float uvleft =  (float) (outsize - Math.sin(Math.toRadians(60)) * outsize);
		uv[0] = new Vector2f(outsize, outsize);
		
		uv[1] = new Vector2f(outsize, 0);
		
		uv[2] = new Vector2f(uvleft, 0.25f);
		uv[3] = new Vector2f(uvleft, 0.75f);
		
		uv[4] = new Vector2f(outsize, 1f);
		
		uv[5] = new Vector2f(1f - uvleft, 0.75f);
		uv[6] = new Vector2f(1f - uvleft, 0.25f);
		
		uv[7] = uv[1];
		
		waterUv[0] = new Vector2f(outsize, outsize);
		
		waterUv[1] = new Vector2f(outsize, 0);
		
		waterUv[2] = new Vector2f(0, 0.25f);
		waterUv[3] = new Vector2f(0, 0.75f);
		
		waterUv[4] = new Vector2f(outsize, 1f);
		
		waterUv[5] = new Vector2f(1f, 0.75f);
		waterUv[6] = new Vector2f(1f, 0.25f);
		
		waterUv[7] = waterUv[1];
	}
	
	@Override
	public HexMapCell[][] createHexMapCells(HexMapChunks chunks, int[][] typeMatrix) {
		HexMapCell[][] cells = new HexMapCell[typeMatrix.length][];
		int[] types = null;
		HexMapCell cell = null;
		TerrainType terrainType = null;
		for(int row=0; row<typeMatrix.length; row ++) {
			types = typeMatrix[row];
			cells[row] = new HexMapCell[types.length];
			for(int col=0; col<types.length; col ++) {
				terrainType = terrainTypes[types[col]];
				cell = HexMapCell.createHexMapCell(cellTerrainRenderer, terrainType, row, col);
				this.create(cell);
				this.setCellIndex(cell, row, col);
				this.setNeighbor(cells, cell);
				chunks.addHexMapCell(row, col, cell);
				cells[row][col]  = cell;
				//地形
				terrainType.update(this, cell);
				if(terrainType.hasWater()) {
					//添加水
					waterCellIndex.add(new HexMapCellIndex(row, col));
				}
			}
		}
		return cells;
	}
	
	protected void create(HexMapCell cell) {
		Vector3f vertex = null;
		Vector2f uv = null;
		for(int i=0; i<VERTICE_SIZE; i++) {
			vertex = new Vector3f();
			vertex.set(this.vertice[i]);
			cell.getVertice().add(vertex);
			uv = new Vector2f();
			uv.set(this.uv[i]);
			cell.getUv().add(uv);
			cell.getNormals().add(new Vector3f(0, 1f, 0));
		}
	}
	
	protected void setCellIndex(HexMapCell cell, int row, int col) {
		Vector3f position = new Vector3f(
				cellOutSize * 2 * col + (row % 2) * cellOutSize, 
				0, 
				(float) (2 * row * cellOutSize * Math.sin(Math.toRadians(60))));
		Vector2f offset = new Vector2f(
				0.5f * (row % 2) + 1.0f * col,
				(float) Math.sin(Math.toRadians(60)) * row);
		Iterator<Vector3f> it = cell.getVertice().iterator();
		while(it.hasNext()) {
			it.next().add(position);
		}
		int index = 0;
		Iterator<Vector2f> uvit = cell.getUv().iterator();
		Vector2f uv = null;
		while(uvit.hasNext()) {
			uv = uvit.next();
			uv.set(this.uv[index ++]);
			uv.add(offset);
		}
	}
	
	@Override
	public List<HexMapCrevice> createHexMapCrevices(HexMapChunks chunks, HexMapCell[][] cells) {
		List<HexMapCrevice> result = new ArrayList<HexMapCrevice>();
		HexMapCrevice crevice = null;
		HexMapCell[] rowCells = null;
		for(int row=0; row<cells.length; row++) {
			rowCells = cells[row];
			for(int col=0; col<rowCells.length; col++) {
				if((crevice = HexMapCrevice.createHexMapCrevice(creviceTerrainRenderer, cells, CREVICE_VERTICE_ALPHA, row, col, Direction.DIRECTION_0)) != null) {
					create(crevice);
					setNeighbor(crevice);
					result.add(crevice);
					chunks.addHexMapCrevice(row, col, crevice);
				}
				if((crevice = HexMapCrevice.createHexMapCrevice(creviceTerrainRenderer, cells, CREVICE_VERTICE_ALPHA, row, col, Direction.DIRECTION_1)) != null) {
					create(crevice);
					setNeighbor(crevice);
					result.add(crevice);
					chunks.addHexMapCrevice(row, col, crevice);
				}
				if((crevice = HexMapCrevice.createHexMapCrevice(creviceTerrainRenderer, cells, CREVICE_VERTICE_ALPHA, row, col, Direction.DIRECTION_2)) != null) {
					create(crevice);
					setNeighbor(crevice);
					result.add(crevice);
					chunks.addHexMapCrevice(row, col, crevice);
				}
				
			}
		}
		return result;
	}

	protected void create(HexMapCrevice crevice) {
		int[] indice = null;
		if(crevice.getDirector() == Direction.DIRECTION_0) {
			indice = new int[] {7, 6, 3, 4};
		} else if(crevice.getDirector() == Direction.DIRECTION_1) {
			indice = new int[] {6, 5, 2, 3};
		} else if(crevice.getDirector() == Direction.DIRECTION_2) {
			indice = new int[] {5, 4, 1, 2};
		}
		int index = 0;
		HexMapCell[] cells = crevice.getCells();
		for(int i=0; i<CREVICE_VERTICE_SIZE; i ++) {
			index = i > 1 ? 1 : 0;
			crevice.getVertice().add(cells[index].getVertice().get(indice[i]));
			crevice.getUv().add(cells[index].getUv().get(indice[i]));
			crevice.getNormals().add(new Vector3f());
		}
		NormalUtils.buildNormal(
				crevice.getVertice().get(2), crevice.getVertice().get(0), crevice.getVertice().get(1), 
				crevice.getNormals().get(0));
		NormalUtils.buildNormal(
				crevice.getVertice().get(0), crevice.getVertice().get(1), crevice.getVertice().get(2), 
				crevice.getNormals().get(1));
		NormalUtils.buildNormal(
				crevice.getVertice().get(3), crevice.getVertice().get(2), crevice.getVertice().get(0), 
				crevice.getNormals().get(2));
		NormalUtils.buildNormal(
				crevice.getVertice().get(1), crevice.getVertice().get(3), crevice.getVertice().get(2), 
				crevice.getNormals().get(3));
		indice = null;
	}
	
	@Override
	public List<HexMapTriangle> createHexMapTriangles(HexMapChunks chunks, HexMapCell[][] cells) {
		List<HexMapTriangle> result = new ArrayList<HexMapTriangle>();
		HexMapTriangle triangle = null;
		HexMapCell[] rowCells = null;
		for(int row = 0; row<cells.length; row++) {
			rowCells = cells[row];
			for(int col = 0; col<rowCells.length; col ++) {
				//右侧
				if(HexMapCell.getHexMapCell(cells.length, rowCells.length, row, col, Direction.DIRECTION_1) != null) {
					//右上
					if((triangle = HexMapTriangle.createHexMapTriangle(triangleTerrainRenderer, cells, TRIANGLE_VERTICE_ALPHA, row, col, 0)) != null) {
						create(triangle);
						setNeighbor(triangle);
						result.add(triangle);
						chunks.addHexMapTriangle(row, col, triangle);
					}
					//右下
					if((triangle = HexMapTriangle.createHexMapTriangle(triangleTerrainRenderer, cells, TRIANGLE_VERTICE_ALPHA, row, col, 1)) != null) {
						create(triangle);
						setNeighbor(triangle);
						result.add(triangle);
						chunks.addHexMapTriangle(row, col, triangle);
					}
				}
			}
		}
		return result;
	}

	public void create(HexMapTriangle triangle) {
		int[] indice = null;
		if(triangle.getDirector() == 0) {
			indice = new int[] {6, 2, 4};
		} else if(triangle.getDirector() == 1) {
			indice = new int[] {5, 1, 3};
		}
		HexMapCell[] cells = triangle.getCells();
		for(int i=0; i<TRIANGLE_VERTICE_SIZE; i++) {
			triangle.getVertice().add(cells[i].getVertice().get(indice[i]));
			triangle.getUv().add(cells[i].getUv().get(indice[i]));
			triangle.getNormals().add(new Vector3f());
		}
		NormalUtils.buildNormal(
				triangle.getVertice().get(2), triangle.getVertice().get(0), triangle.getVertice().get(1), 
				triangle.getNormals().get(0));
		NormalUtils.buildNormal(
				triangle.getVertice().get(0), triangle.getVertice().get(1), triangle.getVertice().get(2), 
				triangle.getNormals().get(1));
		NormalUtils.buildNormal(
				triangle.getVertice().get(1), triangle.getVertice().get(2), triangle.getVertice().get(0), 
				triangle.getNormals().get(2));
		indice = null;
	}
	
	@Override
	public Material createWaterMaterial() {
		return waterMaterial;
	}

	@Override
	public List<HexMapWaterCell> createHexMapWaterCells(HexMapChunks chunks, HexMapCell[][] cells) {
		List<HexMapWaterCell> waters = new ArrayList<HexMapWaterCell>();
		Iterator<HexMapCellIndex> it = this.waterCellIndex.iterator();
		List<HexMapCellIndex> indice = new ArrayList<HexMapCellIndex>();
		HexMapCellIndex index = null;
		HexMapWaterCell water = null;
		//HexMapCell cell = null;
		//HexMapCell[] rounds = null;
		while(it.hasNext()) {
			index = it.next();
			water = createHexMapWaterCell(chunks, index);
			waters.add(water);
			//周围也添加水
//			cell = index.getHexMapCell(cells);
//			rounds = cell.getCells();
//			for(HexMapCell other: rounds) {
//				if(other != null) {
//					index = new HexMapCellIndex(other.getRow(), other.getCol());
//					if(!waterCellIndex.contains(index) && !indice.contains(index)) {
//						indice.add(index);
//						water = createHexMapWaterCell(chunks, index);
//						waters.add(water);
//					}
//				}
//			}
		}
		indice.clear();
		indice = null;
		return waters;
	}
	
	protected HexMapWaterCell createHexMapWaterCell(HexMapChunks chunks, HexMapCellIndex index) {
		HexMapWaterCell water = HexMapWaterCell.createHexMapWaterCell(cellTerrainRenderer, index.getRow(), index.getCol());
		create(water);
		setCellIndex(water, index.getRow(), index.getCol());
		chunks.addHexMapWaterCell(index.getRow(), index.getCol(), water);
		return water;
	}
	
	protected void create(HexMapWaterCell cell) {
		Vector3f vertex = null;
		Vector2f uv = null;
		for(int i=0; i<VERTICE_SIZE; i++) {
			vertex = new Vector3f();
			vertex.set(this.waterVertice[i]);
			cell.getVertice().add(vertex);
			uv = new Vector2f();
			uv.set(this.uv[i]);
			cell.getUv().add(uv);
		}
	}
	
	protected void setCellIndex(HexMapWaterCell cell, int row, int col) {
		Vector3f position = new Vector3f(
				cellOutSize * 2 * col + (row % 2) * cellOutSize, 
				0, 
				(float) (2 * row * cellOutSize * Math.sin(Math.toRadians(60))));
		Iterator<Vector3f> it = cell.getVertice().iterator();
		while(it.hasNext()) {
			it.next().add(position);
		}
	}

	@Override
	public Texture[] createTextures() {
		if(textures == null) {
			if(this.texture_images != null) {
				int len = this.texture_images.length;
				textures = new Texture[len];
				for(int i=0; i<len; i++) {
					textures[i] = Texture.newInstance(texture_images[i], TextureMipmapPloy.getInstance());
				}
			} else {
				int len = this.texture_paths.length;
				textures = new Texture[len];
				for(int i=0; i<len; i++) {
					try {
						textures[i] = Texture.newInstance(Constants.getGameFileInputStream(this.texture_paths[i]), TextureMipmapPloy.getInstance());
					} catch (FileNotFoundException e) {
						log.error("无法找到地形纹理文件", e);
					}
				}
			}
		}
		return textures;
	}

	@Override
	public float getCellOutSize() {
		return this.cellOutSize;
	}

	public float getCellInSize() {
		return cellInSize;
	}

	public TerrainType[] getTerrainTypes() {
		return terrainTypes;
	}

	public Material getWaterMaterial() {
		return waterMaterial;
	}

	@Override
	public Texture createWaterNoiseTexture() {
		return Texture.newInstance(
				DefaultTerrainFactory.class.getClassLoader().getResourceAsStream("images/noise.png"), 
				TextureMipmapPloy.getInstance());
	}

	@Override
	public CollisionShape createCollisionShape(
			int rows, int cols, HexMapCell[][] cells, List<HexMapCrevice> crevices,
			List<HexMapTriangle> triangles, List<HexMapWaterCell> waters) {
		int numTrianglesCell = rows * cols * 6;
		int numTrianglesCrevice = crevices.size() * 2;
		int numTrianglesTriangle = triangles.size();
		int numTrianglesWater = waters.size() * 6;
		int numTriangles = numTrianglesCell + numTrianglesCrevice + numTrianglesTriangle + numTrianglesWater + numTrianglesWater;
		ByteBuffer indexBuffer = BufferBuilder.buildByteBuffer(numTriangles * 3 * 4);
		int triangleStride = 12;
		int numVertices = rows * cols * VERTICE_SIZE + waters.size() * VERTICE_SIZE;
		ByteBuffer verticeBuffer = BufferBuilder.buildByteBuffer(numVertices * 3 * 4);
		int vertexStride = 12;
		List<Vector3f> vertice = null;
		int index = 0;
		//地面
		for(int row=0; row<rows; row ++) {
			for(int col=0; col<cols; col ++) {
				index = (row * cols + col) * VERTICE_SIZE;
				vertice = cells[row][col].getVertice();
				//顶点
				for(Vector3f vertex: vertice) {
					vertex.store(verticeBuffer);
				}
				//索引
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 1);
				indexBuffer.putInt(index + 2);
				
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 2);
				indexBuffer.putInt(index + 3);
				
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 3);
				indexBuffer.putInt(index + 4);
				
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 4);
				indexBuffer.putInt(index + 5);
				
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 5);
				indexBuffer.putInt(index + 6);
				
				indexBuffer.putInt(index);
				indexBuffer.putInt(index + 6);
				indexBuffer.putInt(index + 7);
			}
		}
		//水顶点
		for(HexMapWaterCell cell: waters) {
			index += VERTICE_SIZE;
			vertice = cell.getVertice();
			//顶点
			for(Vector3f vertex: vertice) {
				vertex.store(verticeBuffer);
			}
			//索引
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 1);
			indexBuffer.putInt(index + 2);
			
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 2);
			indexBuffer.putInt(index + 3);
			
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 3);
			indexBuffer.putInt(index + 4);
			
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 4);
			indexBuffer.putInt(index + 5);
			
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 5);
			indexBuffer.putInt(index + 6);
			
			indexBuffer.putInt(index);
			indexBuffer.putInt(index + 6);
			indexBuffer.putInt(index + 7);
		}
		//缝隙
		int[] indice = null;
		HexMapCell[] cellArray = null;
		int indexRight = 0;
		for(HexMapCrevice crevice: crevices) {
			cellArray = crevice.getCells();
			if(crevice.getDirector() == Direction.DIRECTION_0) {
				indice = new int[] {7, 6, 3, 4};
			} else if(crevice.getDirector() == Direction.DIRECTION_1) {
				indice = new int[] {6, 5, 2, 3};
			} else if(crevice.getDirector() == Direction.DIRECTION_2) {
				indice = new int[] {5, 4, 1, 2};
			}
			index = (cellArray[0].getRow() * rows + cellArray[0].getCol()) *  VERTICE_SIZE;
			indexRight = (cellArray[1].getRow() * rows + cellArray[1].getCol()) * VERTICE_SIZE;
			indexBuffer.putInt(index + indice[0]);
			indexBuffer.putInt(index + indice[1]);
			indexBuffer.putInt(indexRight + indice[2]);
			
			indexBuffer.putInt(indexRight + indice[2]);
			indexBuffer.putInt(index + indice[1]);
			indexBuffer.putInt(indexRight + indice[3]);
		}
		//三角缝隙
		for(HexMapTriangle triangle: triangles) {
			if(triangle.getDirector() == 0) {
				indice = new int[] {6, 2, 4};
			} else if(triangle.getDirector() == 1) {
				indice = new int[] {5, 1, 3};
			}
			cellArray = triangle.getCells();
			for(int i=0; i<TRIANGLE_VERTICE_SIZE; i++) {
				index = (cellArray[i].getRow() * rows + cellArray[i].getCol()) * VERTICE_SIZE;
				indexBuffer.putInt(index + indice[i]);
			}
		}
		indexBuffer.rewind();
		verticeBuffer.rewind();
		TriangleIndexVertexArray array = new TriangleIndexVertexArray(numTriangles, indexBuffer, triangleStride, numVertices, verticeBuffer, vertexStride);
		return new BvhTriangleMeshShape(array, false);
	}

	
}
